#include<iostream>
#include<conio.h>
#include<string.h>

using namespace std;

bool error=false;
bool errorread=false;

struct Stack
{
	char data;
	Stack *pNext;
};

typedef struct Stack *stack;

void createStack(stack &st)
{
	st=NULL;
}

int IsEmpty(stack &st)
{
	if(st==NULL)
		return 1;
	return 0;
}

void Push(stack &st,char c)
{
	stack node;
	node=(stack)malloc(sizeof(struct Stack));
	node->data=c;
	node->pNext=st;
	st=node;
}

char Pop(stack &st)
{
	char c; 
	stack s;
	if(st==NULL)
	{
		error=true;
		exit(1);;
	}
	c=st->data;
	s=st;
	st=s->pNext;
	delete(s);
	return c;
}

char Top(stack &st)
{
	if(st==NULL)
	{
		return'\0';
	}
	return st->data;
}

int ToanTu(char ele)
{
	if(ele=='+'||ele=='-'||ele=='*'||ele=='/')
		return 1;
	return 0;	
}

int UuTien(char ToanTu)
{
	int uutien=-1;
	switch(ToanTu)
	{
	case '*':
	case '/':
		uutien=5;
		break;
	case '+':
	case '-':
		uutien=4;
		break;
	default:
		uutien=0;
	}
	return uutien;
}

void PushPlus(char c,char *stack,int i)
{
	stack[i]=c;
	stack[i+1]='\0';
}

void InfixToPostfix(char *infix,char *postfix)
{
	int j=0;
	stack S;
	createStack(S);
	char curChar;
	int len=strlen(infix);
	for(int i=0;i<len;i++)
	{
		curChar=infix[i];
		if(ToanTu(curChar)==1)
		{
			int rank1=UuTien(curChar);
			int rank2=UuTien(Top(S));
			if(rank1>rank2)
				Push(S,curChar);
			else
			{
				while(rank1<=rank2)
				{
					if(Top(S)==NULL)
						break;
					PushPlus(Pop(S),postfix,j++);
					rank2=UuTien(Top(S));
				}
				Push(S,curChar);
			}
		}
		else
		{
			if(curChar=='(')
				Push(S,curChar);
			else 
				if(curChar==')')
				{
					char temp=Pop(S);
					while(temp!='(')
					{
						PushPlus(temp,postfix,j++);
						temp=Pop(S);
					}
				}
				else
					PushPlus(curChar,postfix,j++);
		}
	}
	while(Top(S)!=NULL)
	{
		PushPlus(Pop(S),postfix,j++);
	}				
}

float TinhToan(char ToanTu,float a,float b)
{
	switch(ToanTu)
	{
	case '+':
		return a+b;
	case '-':
		return a-b;
	case '*':
		return a*b;
	case '/':
		if(b==0)
		{
			error=true;
			exit(-2);
		}
		return a/b;
	}
}

float Value(char *postfix)
{
	float val[100];
	int top=-1;
	int len=strlen(postfix);
	for(int i=0;i<len;i++)
	{
		char curChar=postfix[i];
		if(ToanTu(curChar)==0)
		{
			char s[2];
			s[0]=curChar;
			s[1]='\0';
			float res=atof(s);
			top++;
			val[top]=res;
		}
		else
		{
			if(ToanTu(curChar)==1)
			{
				float res2=val[top];
				top--;
				if(top<0)
				{
					error=true;
					exit(-1);
				}
				float res1=val[top];
				float res3=TinhToan(curChar,res1,res2);
				val[top]=res3;
			}
		}
	}
	if (top>1)
	{
		error=true;
		cout<<top;
		exit(-1);
	}
	return val[top];
}

char *read(char *s)
{
	FILE *f;
	char *str;
	str=new char [100];
	f=fopen(s,"rt");
	if(f==NULL)
		errorread=true;
	else
	{
		while(!feof(f))
		{
			fgets(str,256,f);
		}
		fclose(f);
	}
	return str;
}

void write(char *s,char *str,float kq)
{
	FILE *f;
	f=fopen(s,"wt");
	if(f!=NULL)
	{
		fprintf(f,str);
		fprintf(f,"\n%f",kq);
		fclose(f);
	}
}

void main()
{
	stack S;
	createStack(S);
	char *str1,*str2;
	str1=read("input.txt");
	if(errorread)
	{
		write("09520169.txt","Da co Loi Trong Qua Trinh Doc File",NULL);
		return;
	}
	str2=new char[100];
	for(int i=0;i<strlen(str1);i++)
	{
		Push(S,str1[i]);
	}
	InfixToPostfix(str1,str2);
	float kq=Value(str2);
	if(error)
	{
		write("09520169.txt","Da co Loi Trong Qua Trinh Tinh Toan",NULL);
		return;
	}
	write("09520169.txt",str2,kq);
}